Skip to content

feat(revive): add contract instantiated event#8789

Merged
athei merged 8 commits intoparitytech:masterfrom
voliva:revive-instantiated-evt
Jun 25, 2025
Merged

feat(revive): add contract instantiated event#8789
athei merged 8 commits intoparitytech:masterfrom
voliva:revive-instantiated-evt

Conversation

@voliva
Copy link
Copy Markdown
Contributor

@voliva voliva commented Jun 6, 2025

Description

This PR adds the Instantiated event for pallet-revive for the top frame. Addresses issue #8677

This might need refreshing the weights of bot instantiate and instantiate_with_code, as it emits a new event.

Integration

No additional work is needed to integrate this feature. The pallet will emit on Instantiated event every time instantiate or instantiate_with_code successfully performs an instantiation.

Checklist

  • My PR includes a detailed description as outlined in the "Description" and its two subsections above.
  • My PR follows the labeling requirements of this project (at minimum one label for T required)
    • External contributors: ask maintainers to put the right label on your PR.
  • I have made corresponding changes to the documentation (if applicable)
  • I have added tests that prove my fix is effective or that my feature works (if applicable)

Comment on lines +1145 to +1151
assert_eq!(
&events(),
&[Event::Instantiated {
deployer: ALICE_ADDR,
contract: instantiated_contract_address
}]
);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only test that was effected.

I've checked there's also a test that already checks the case when the instantiation call succeeds but the contract is reverted - In that case there's already an assertion that checks that no events should be emitted. See instantiation_fails_with_failing_output.

All these tests were done previously, but updated the event assertions when #7164 removed the events. The only one that needed to be updated is this one.

Comment on lines +829 to +837
let result = stack
.run(executable, input_data)
.map(|_| (address, stack.first_frame.last_frame_output))
.map(|_| (address, stack.first_frame.last_frame_output));
if let Ok((contract, ref output)) = result {
if !output.did_revert() {
Contracts::<T>::deposit_event(Event::Instantiated { deployer, contract });
}
}
result
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this within exec, in run_instantiate which is called only from the top frame. The other possibility was to have this in bare_instantiate of the pallet's lib.rs, but I thought it would be better to have it in here since this is the function performing the instantiation (and some tests are actually calling this function directly).

@voliva
Copy link
Copy Markdown
Contributor Author

voliva commented Jun 6, 2025

CC @pgherveou @athei

Can you add the appropriate labels please? 🙏

@bkchr bkchr requested review from athei and pgherveou June 8, 2025 10:07
Copy link
Copy Markdown
Member

@athei athei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocked until you convinced me that we need that. Let's discuss in the issue.

@xermicus
Copy link
Copy Markdown
Member

I am confused. I thought we had performance issues and thus needed to reduce among others this exact event (which is entirely unnecessary anyways)?

@josepot
Copy link
Copy Markdown
Contributor

josepot commented Jun 16, 2025

I thought we had performance issues and thus needed to reduce among others this exact event

This event (emitted just for the top frame) does NOT have a performance impact. It's actually very obvious that it doesn't have a performance impact, what makes you think that it does?

On the other hand, not having this event is going to make the DX quite horrendous and as @voliva has explained several times: removing this event unnecessarily breaks an assumption of previous libraries and tooling.

@xermicus
Copy link
Copy Markdown
Member

xermicus commented Jun 16, 2025

He even writes in the PR description This might need refreshing the weights and now you are telling me this has 0 impact?

My position stays the same regardless of how big or small you think the negative impact is. This is entirely unnecessary. I see a problem solved here on-chain which can solved off-chain and this is never good. We are trying to move closer to Ethereum so why add something like this? People start relying on it and then we won't be able to change or remove in the future.

@voliva
Copy link
Copy Markdown
Contributor Author

voliva commented Jun 16, 2025

For more context regarding this, please read the conversation in the original issue #8677. This morning I added one comment summarising why we need this and why it wouldn't bring back the performance issue you're mentioning.

And yes, I said "This might need refreshing the weights" because I'm not sure myself if emitting one single event in a transaction is worth recalculating the weights, given how insignificant it is towards the total weight. If it is, then sure, let's refresh them. I'll need some help though, as I'm not sure how to run benchmarks in the specified targets while being an external contributor.

@josepot
Copy link
Copy Markdown
Contributor

josepot commented Jun 20, 2025

and now you are telling me this has 0 impact?

Yes, that's what I'm telling you. The performance impact is completely negligible, obviously. Do you want me to explain to you why?

My position stays the same regardless of how big or small you think the negative impact is.

Then why in the world would you bring the performance impact into the discussion? 😅

I see a problem solved here on-chain which can solved off-chain and this is never good.

People start relying on it and then we won't be able to change or remove in the future.

It's actually the other way around. By removing this event you are forcing your consumers to rely into an arbitrary implementation detail... because the way that you are calculating this address is not something that has been properly documented or standarized. That formula is just an arbitrary (and probably not that great) implementation detail, which I bet is going to change any day, and when that day comes, then every off-chain consumer will have to deal with the mess. The event, on the other hand, is a clean API that allows us not to have to rely on these arbitrary implementation details.

Not to mention the fact that it would also allow you to write better tests, that don't rely on internals.

@pgherveou
Copy link
Copy Markdown
Contributor

Ok sorry to let this drag, it's been a couple of busy weeks.
The team is gathering this week, this should be quick to figure out, let's try to get to a solution by the end of the week.

and now you are telling me this has 0 impact?
Yes, that's what I'm telling you. The performance impact is completely negligible, obviously. Do you want me to explain to you why?

I think we can agree that emitting a single event for the top-level frame has no significant performance impact.
However, emitting it for every frame that instantiates a contract could start to matter.
So, if we go with this solution, the PR is fine as it stands, I’d just suggest we find a better name for the event to make it clearer that not all instantiations emit it — only the one from the original instantiate transaction.

My position stays the same regardless of how big or small you think the negative impact is.
Then why in the world would you bring the performance impact into the discussion? 😅

I think our stance is that we should try as much as possible to embrace Ethereum convention and not add new one, as it makes things harder to document, maintain, and can have perfomance implications

I see a problem solved here on-chain which can solved off-chain and this is never good.
People start relying on it and then we won't be able to change or remove in the future.
It's actually the other way around. By removing this event you are forcing your consumers to rely into an arbitrary implementation detail... because the way that you are calculating this address is not something that has been properly documented or standarized. That formula is just an arbitrary (and probably not that great) implementation detail, which I bet is going to change any day, and when that day comes, then every off-chain consumer will have to deal with the mess. The event, on the other hand, is a clean API that allows us not to have to rely on these arbitrary implementation details.
Not to mention the fact that it would also allow you to write better tests, that don't rely on internals.

These are not arbitrary implementation details, the address derivation logic is defined in the Ethereum yellow paper and in EIPs. Changing it would break the entire ecosystem. That being said I understand that having a single event to rely on would be more convenient for you

@josepot
Copy link
Copy Markdown
Contributor

josepot commented Jun 23, 2025

I think we can agree that emitting a single event for the top-level frame has no significant performance impact.

great!

However, emitting it for every frame that instantiates a contract could start to matter.

I highly doubt it. However, no one is suggesting this.

So, if we go with this solution, the PR is fine as it stands, I’d just suggest we find a better name for the event to make it clearer that not all instantiations emit it — only the one from the original instantiate transaction.

"potato, potahto"... I mean, I still think that the current name is totally adequate. However, I'm more than willing to compromise on the name. Just propose a better one and let's go with that. However, let's please not drag this any further b/c of the name.

I think our stance is that we should try as much as possible to embrace Ethereum convention and not add new one, as it makes things harder to document, maintain, and can have perfomance implications

You are adding a new convention, already! Because with the current implementation the nonce is not only being altered for every new transaction, it's also being altered for every new contract instantiation... So, yeah, no, sorry, this is already different than what Ethereum does, isn't it? If I'm not mistaken, then this test is yielding a false positive. So, yeah, no, sorry, I don't think that's embracing an Ethereum convention. This is trying to be similar, but not the same.

These are not arbitrary implementation details, the address derivation logic is defined in the Ethereum yellow paper and in EIPs.

The way that the nonce is being altered (which ends up affecting the address being computed) is what's an implementation detail, and since you are going to change that any day by now, we should not rely on it.

That being said I understand that having a single event to rely on would be more convenient for you

It's not that it's more convenient for me. If this event had been present, this pallet could have had better tests, which would have caught the potential regression that was reported (and ignored) weeks ago.

@pgherveou
Copy link
Copy Markdown
Contributor

I'm not mistaken, then this test is yielding a false positive

what is the false positive here ?

It's not that it's more convenient for me. If this event had been present, this pallet could have had better tests, which would have caught the potential regression that paritytech/contract-issues#37 (comment).

Runtime upgrade are on hold for now so that patch has probably not been deployed, this should get unstuck on Paseo, once this get enacted paseo-network/passet-hub#16

@josepot
Copy link
Copy Markdown
Contributor

josepot commented Jun 23, 2025

I'm not mistaken, then this test is yielding a false positive

what is the false positive here ?

It's not that it's more convenient for me. If this event had been present, this pallet could have had better tests, which would have caught the potential regression that paritytech/contract-issues#37 (comment).

Runtime upgrade are on hold for now so that patch has probably not been deployed, this should get unstuck on Paseo, once this get enacted paseo-network/passet-hub#16

I mean, my point is that the test is assuming that the nonce is not being increased prior to the first instantiation, which -looking at the code- doesn't seem like an obvious assumption. What I mean is that the test is not testing the whole flow, and that if there was a bug by which the nonce being used for computing the address is, in fact, the updated one, then that test would yield a false positive.

We are trying to actually test this against the latest commit using zombienet, but we haven't succeeded to set it up :/

@pgherveou
Copy link
Copy Markdown
Contributor

I mean, my point is that the test is assuming that the nonce is not being increased prior to the first instantiation, which -looking at the code- doesn't seem like an obvious assumption.

not too sure what you mean, this get the nonce, get the address derived from the nonce, and verify that it matches the address returned by the dry_run, the goal of the test is to test that part.

We are trying to actually test this against the latest commit using zombienet, but we haven't succeeded to set it up :/

if you are just testing this, I would simply use kitchensink, or the dev-node that we added recently (under revive/dev-node)

Copy link
Copy Markdown
Member

@athei athei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one minor nit.

Comment thread substrate/frame/revive/src/lib.rs Outdated
@athei athei self-requested a review June 24, 2025 09:33
@josepot
Copy link
Copy Markdown
Contributor

josepot commented Jun 24, 2025

not too sure what you mean, this get the nonce, get the address derived from the nonce, and verify that it matches the address returned by the dry_run, the goal of the test is to test that part.

What I mean is that IMO this assertion should be done in a similar way to what it's being done in here.

Meaning that there should be a real transaction performing a real contract instantiation, and the test should check that the address being produced does, in fact, match with the one that comes from the dry-run.

The main reason being that by the time that the contract instantiation happens, then the nonce has already being increased. However, there is specific logic that tries to compensate for that. So, if one day this kind of logic changed, then this test would produce a false positive.

In short: the output of the dry-run should be tested against the "output" of a real transaction. I think that the instantiated event would be useful for such test.

if you are just testing this, I would simply use kitchensink, or the dev-node that we added recently (under revive/dev-node)

Thanks a lot for this! we did use it and I'm happy to stand corrected: that the dry_run is currently returning the correct contract address. Thank you!

@athei
Copy link
Copy Markdown
Member

athei commented Jun 24, 2025

/cmd fmt

@athei athei added the T7-smart_contracts This PR/Issue is related to smart contracts. label Jun 24, 2025
@athei athei enabled auto-merge June 24, 2025 10:24
@voliva
Copy link
Copy Markdown
Contributor Author

voliva commented Jun 25, 2025

One of the CI checks has failed with a "context cancelled". Is there somethingI need to fix in this PR?

@athei
Copy link
Copy Markdown
Member

athei commented Jun 25, 2025

Just random CI failure. Just re-running.

@athei athei added this pull request to the merge queue Jun 25, 2025
Merged via the queue into paritytech:master with commit 4a869b9 Jun 25, 2025
244 checks passed
@voliva voliva deleted the revive-instantiated-evt branch June 25, 2025 20:30
@Polkadot-Forum
Copy link
Copy Markdown

This pull request has been mentioned on Polkadot Forum. There might be relevant details there:

https://forum.polkadot.network/t/sponsorship-for-active-devs-and-community-members-during-polkadot-symbiosis-in-buenos-aires/14723/92

alvicsam pushed a commit that referenced this pull request Oct 17, 2025
# Description

This PR adds the `Instantiated` event for pallet-revive for the top
frame. Addresses issue #8677

This might need refreshing the weights of bot `instantiate` and
`instantiate_with_code`, as it emits a new event.

## Integration

No additional work is needed to integrate this feature. The pallet will
emit on `Instantiated` event every time `instantiate` or
`instantiate_with_code` successfully performs an instantiation.

# Checklist

* [x] My PR includes a detailed description as outlined in the
"Description" and its two subsections above.
* [x] My PR follows the [labeling requirements](

https://github.com/paritytech/polkadot-sdk/blob/master/docs/contributor/CONTRIBUTING.md#Process
) of this project (at minimum one label for `T` required)
* External contributors: ask maintainers to put the right label on your
PR.
* [x] I have made corresponding changes to the documentation (if
applicable)
* [x] I have added tests that prove my fix is effective or that my
feature works (if applicable)

---------

Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Alexander Theißen <alex.theissen@me.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T7-smart_contracts This PR/Issue is related to smart contracts.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants